from rest_framework import serializers
from rest_framework import mixins
from rest_framework import generics
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.permissions import BasePermission
from ..models import UserProfile, Book

# Django REST framework 视图三层封装
# 说明，这里的三层封装是指 APIView、mixins(mixins.ListModelMixin、generic.GenericAPIView和generics.ListAPIView)、viewsets
# 在项目中，通常使用 APIView 和 viewsets， 而 mixins 存在的价值更多的是用于理解视图封装的原理，从APIView到viewsets就是mixins封装的
# APIView的示例见 bookApi.py
# 1. 用 minixs.ListModelMixin+GenericAPIView 的方式实现视图封装
# 2. 用 generics.ListAPIView 的方式实现视图封装
# 3. 用 viewsets+Router 的方式实现视图封装


class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model=Book
        # fields=('title', 'isbn', 'author') # 指定序列化某些字段
        fields="__all__" # 将整个表的所有字段都序列化


class BookMixinView1(mixins.ListModelMixin, generics.GenericAPIView):
    """
    用 minixs.ListModelMixin+GenericAPIView 的方式实现视图封装
    """
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

    # 如果这里不加get函数，代表默认不支持get访问这个api，所以必须加上
    def get(self, request, *args, **kwargs):
        apikey = self.request.query_params.get('apikey', 0)
        developer = UserProfile.objects.filter(APIkey=apikey).first()
        if developer:
            balance = developer.money
            if balance > 0:
                isbn = self.request.query_params.get('isbn', 0)
                developer.money -= 1
                developer.save()
                self.queryset = Book.objects.filter(isbn=int(isbn))
                return self.list(request, *args, **kwargs)
            else:
                return Response("兄弟，没钱了！")
        else:
            return Response("查无此人")


class BookMixinView2(generics.ListAPIView):
    """
    用 generics.ListAPIView 的方式实现视图封装（和上面比较，其实这有 generics.ListAPIView 这里不同罢了）
    """
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

    # 可以不加get函数，因为 generics.ListAPIView 相对于 mixins.ListModelMixin+generics.GenericAPIView
    # 而言，所谓的封装就是封装了一个 get 函数罢了
    def get(self, request, *args, **kwargs):
        apikey = self.request.query_params.get('apikey', 0)
        developer = UserProfile.objects.filter(APIkey=apikey).first()
        if developer:
            balance = developer.money
            if balance > 0:
                isbn = self.request.query_params.get('isbn', 0)
                developer.money -= 1
                developer.save()
                self.queryset = Book.objects.filter(isbn=int(isbn))
                return self.list(request, *args, **kwargs)
            else:
                return Response("兄弟，没钱了！")
        else:
            return Response("查无此人")


class IsDeveloper(BasePermission):
    message = '查无此人'

    def has_permission(self, request, view):
        apikey = request.query_params.get('apikey', 0)
        developer = UserProfile.objects.filter(APIkey=apikey).first()
        if developer:
            return True
        else:
            print(self.message)
            return False


class EnoughMoney(BasePermission):
    message = '兄弟，没钱了！'

    def has_permission(self, request, view):
        apikey = request.query_params.get('apikey', 0)
        developer = UserProfile.objects.filter(APIkey=apikey).first()
        balance = developer.money
        if balance > 0:
            developer.money -= 1
            developer.save()
            return True
        else:
            print(self.message)
            return False


class BookModelViewSet(viewsets.ModelViewSet):
    """
    用 viewsets+Router 的方式实现视图封装
    """
    authentication_classes = []
    permission_classes = [IsDeveloper, EnoughMoney]
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer

    def get_queryset(self):
        isbn = self.request.query_params.get('isbn', 0)
        books = Book.objects.filter(isbn=int(isbn))
        queryset = books
        return queryset
